﻿using Common.Framework.Core.Extension;
using Common.Framework.Core.FluentValidation;
using Common.Framework.Core.Jwt;
using Common.Framework.Core.Middleware;
using Common.Framework.Core.Minio;
using Common.Framework.Core.Snowflake;
using Common.Framework.Core.SqlSugar;
using Common.Framework.Core.Swagger;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;

namespace Common.Framework.Core.Foundation
{
    public static class StartupFoundation
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="services"></param>
        /// <param name="Configuration"></param>
        /// <param name="isUseMinio">是否启用minio,true:默认启用.如果是task项目,可能需要启用,请传入false</param>
        /// <returns></returns>
        public static IServiceCollection CustomConfigureServices(this IServiceCollection services, IConfiguration Configuration, bool isUseMinio = true)
        {
            //注册IOptions
            services.AddOptions();

            services.ConfigureSnowflake(Configuration);
            services.ConfigureSqlSugar(Configuration);

            services.AddSuppressModelStateInvalidFilter();

          //  services.AddJwtBearer(Configuration);

            //使用minio
            if (isUseMinio)
            {
                services.ConfigureMinio(Configuration);
            }

            services.AddHttpClient();

            return services;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="app"></param>
        /// <param name="env"></param>
        /// <param name="provider"></param>
        /// <param name="isUseAuthenticationCustom">是否启用自定义授权中间件(默认启用)(如果是纯api接口内部调用,请传false,不启用该中间件,可以提升效率)</param>
        public static void CustomConfigure(this IApplicationBuilder app, IWebHostEnvironment env, IApiVersionDescriptionProvider provider, bool isUseAuthenticationCustom = true)
        {
            if (env.IsDevelopment() || env.IsStaging())
            {
                app.UseDeveloperExceptionPage();

                app.AddUseSwagger(provider);
            }
            app.Use(next => new RequestDelegate(
                     async context =>
                     {
                         context.Request.EnableBuffering();
                         await next(context);
                     }
            ));//请求前获取body
       //     app.UseHttpsRedirection();
           var staticFile = new StaticFileOptions();
            staticFile.FileProvider = new PhysicalFileProvider(env.ContentRootPath);
            app.UseStaticFiles(staticFile);
          
            app.UseRouting();

            app.UseCors(builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()); //跨域    

       //     app.UseAuthentication(); //口诀: 先验证、再授权
        //    app.UseAuthorization(); //加上该行后,Controller、Action才能加上 [Authorize] 属性
            //if (isUseAuthenticationCustom)
            //{
            //    app.UseAuthenticationCustom();
            //}

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }


        /// <summary>
        /// 组合配置
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="builder"></param>
        /// <returns></returns>
        public static IMvcBuilder AddCustomControllers(this IMvcBuilder builder)
        {
            builder.AddCustomConfigureJson().AddCustomFluentValidation();
            return builder;
        }

        /// <summary>
        /// 格式化输出的json
        /// </summary>
        /// <param name="builder"></param>
        /// <returns></returns>
        private static IMvcBuilder AddCustomConfigureJson(this IMvcBuilder builder)
        {
            builder.AddNewtonsoftJson(options =>
            {
                options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                options.SerializerSettings.Converters.Add(new BigIntIdToStringConverter());
            });
            return builder;
        }
    }
}
